#include "stdafx.h"
#include "StateManager.h"
#include "RenderSystem.h"

StateManager::StateManager(Systems* systems) : m_systems(systems), m_run(true), m_next_state(nullptr) {}
StateManager::~StateManager(void){ ClearStates(); }

void StateManager::Shut(){
	PostMessage(m_systems->m_render_system->GetWindowHandle(), WM_QUIT, 0, 0);
	m_run = false;
}


void StateManager::ManageState(const String& p_id, State* p_state) {
	state_info si(p_id, p_state);
	si.m_state->SetSystems(m_systems);
	m_states.push_back(si);
}

State* StateManager::FindById(const String& p_id) {
	for (auto it = m_states.begin(); it != m_states.end(); it++) {
		if (it->m_id == p_id) {
			return it->m_state;
		}
	}
	return nullptr;
}


void StateManager::ChangeState(State* p_state) {
	m_next_state = p_state;
}

bool StateManager::PushState(State* p_state) {
	if (!m_stack.empty()) {
		if (!m_stack.back()->Pause()) {
			return false;
		}
	}
	m_stack.push_back(p_state);
	m_stack.back()->Init();
	return true;
}

void StateManager::PopState() {
	if (!m_stack.empty()) {
		m_stack.back()->Shut();
		m_stack.pop_back();
	}

	if (!m_stack.empty()) {
		m_stack.back()->Resume();
	}
	else {
		Shut();
	}
}

void StateManager::ClearStates() {
	if (!m_stack.empty()) {
		for (auto it = m_stack.begin(); it != m_stack.end(); it++) {
			(*it)->Shut();
			//(*it)->Destroy();
		}
		m_stack.clear();
	}
	if (!m_states.empty()) {
		for (auto it = m_states.begin(); it != m_states.end(); it++){
			(*it).m_state->Destroy();
		}
	}
}

void StateManager::Update(float deltatime){
	if (m_next_state != nullptr){
		if (!m_stack.empty()) {
			m_stack.back()->Shut();
			m_stack.pop_back();
		}
		m_stack.push_back(m_next_state);
		m_stack.back()->Init();
		m_next_state = nullptr;
	}

	if (!m_stack.empty()){
		m_stack.back()->Update(deltatime);
	}
}

void StateManager::Render(){
	if (!m_stack.empty()){
		for (auto it = m_stack.begin(); it != m_stack.end(); it++){
			(*it)->Render();
		}
	}
}

bool StateManager::Init(){
	//m_screen_fade = new ScreenFade;
	//if (!m_screen_fade->Init(m_systems)){
	//	return false;
	//}
	return true;
}